# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time        : 2020/12/3 15:28
@Author      : Albert Darren
@Contact     : 2563491540@qq.com
@File        : special_matrices.py
@Version     : Version 1.0.0
@Description : TODO
@Created By  : PyCharm
"""
import numpy as np


def triple_diagonal_matrix(matrix):
    """
    返回一个三对角矩阵
    :param matrix:
    :return:
    example:
    [[ 1  2  0  0  0  0]
    [ 7  8  9  0  0  0]
    [ 0 14 15 16  0  0]
    [ 0  0 21 22 23  0]
    [ 0  0  0 28 29 30]
    [ 0  0  0  0 35 36]]
    """
    rows, columns = matrix.shape
    for row in range(rows):
        for column in range(columns):
            if abs(row - column) > 1:
                matrix[row][column] = 0
    return matrix


def upper_hessenberg_matrix(matrix):
    """
    返回一个上海森伯格矩阵
    :param matrix:
    :return:
    example:
    [[ 1  2  3  4  5  6]
     [ 7  8  9 10 11 12]
     [ 0 14 15 16 17 18]
     [ 0  0 21 22 23 24]
     [ 0  0  0 28 29 30]
     [ 0  0  0  0 35 36]]
    """
    rows, columns = matrix.shape
    for row in range(rows):
        for column in range(columns):
            if row > column + 1:
                matrix[row][column] = 0
    return matrix


def is_strictly_diagonally_dominant_matrix(square_matrix: np.ndarray):
    rows, columns = square_matrix.shape
    if rows == columns:
        for row in range(rows):
            new_columns = list(range(columns))
            new_columns.pop(row)
            abs_prod = 0
            for column in new_columns:
                abs_prod += abs(square_matrix[row, column])
                if abs(square_matrix[row, row]) <= abs_prod:
                    return False
        return True
    else:
        raise Exception("please pass a square matrix")


def is_weakly_diagonally_dominant_matrix(square_matrix: np.ndarray):
    rows, columns = square_matrix.shape
    if rows == columns:
        for row in range(rows):
            new_columns = list(range(columns))
            new_columns.pop(row)
            abs_prod = 0
            for column in new_columns:
                abs_prod += abs(square_matrix[row, column])
                if abs(square_matrix[row, row]) > abs_prod:
                    return True
        return False
    else:
        raise Exception("please pass a square matrix")


def hilbert_matrix(order: int):
    hilbert = np.zeros((order, order))
    for i in range(order):
        for j in range(order):
            hilbert[i, j] = 1 / (i + j + 1)
    return hilbert


def reducible_matrix():
    pass


if __name__ == '__main__':
    # A = np.arange(1, 37).reshape(6, 6)
    # print(upper_hessenberg_matrix(A))
    # print(triple_diagonal_matrix(A))
    # 第二组测试方程组，来源详见李庆扬数值分析第5版P209
    A = np.array([[5, 2, 1], [-1, 4, 2], [2, -3, 10]], dtype=np.float64)
    print(is_strictly_diagonally_dominant_matrix(A))
